home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / others / lissajou.zip / LISSAJOU.C < prev    next >
Text File  |  1991-05-07  |  13KB  |  407 lines

  1. /*  the LISSAJOU application by K.Steffens (STEFFENS@DMSWWU5P.BITNET)
  2.     this program is donated to the public domain as long as it is
  3.     distributed together with the sources and the executable */
  4.  
  5. #include <windows.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <math.h>
  9. #include "lissajou.h"
  10.  
  11. /* the function prototypes */
  12. int PASCAL WinMain(HANDLE,HANDLE,LPSTR,int);
  13. BOOL InitApplication(HANDLE);
  14. long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
  15. BOOL FAR PASCAL About(HWND, unsigned, WORD, LONG);
  16. BOOL FAR PASCAL SetParams(HWND, unsigned, WORD, LONG);
  17. BOOL FAR PASCAL TurnLeft(HWND, unsigned, WORD, LONG);
  18. BOOL FAR PASCAL TurnRight(HWND, unsigned, WORD, LONG);
  19. BOOL FAR PASCAL StatusBox(HWND, unsigned, WORD, LONG);
  20. void LissajousPlot(HDC, WORD, WORD);
  21.  
  22. HANDLE hInst, hAccTable;
  23. float x_fact, y_fact, d_phi, r_phi;
  24. int n_steps,r_speed, iDirection;
  25. WORD idTimer;
  26. BOOL bAutoRotate, bStatusBox;
  27. HMENU hMenu;
  28. HWND hStatusBox;
  29.  
  30. /*  Here comes the Main Window function - it is similar to the
  31.     Generic Application Main function from the SDK handbooks */
  32.  
  33. int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  34. HANDLE hInstance;
  35. HANDLE hPrevInstance;
  36. LPSTR lpCmdLine;
  37. int nCmdShow;
  38. {
  39.     MSG msg;
  40.     HWND hWnd;
  41.  
  42.     hInst = hInstance;
  43.  
  44.     /* if no previous instances are there then initialization required */
  45.     if (!hPrevInstance)
  46.         if (!InitApplication(hInstance))
  47.             return (FALSE);         /* Error exit*/
  48.  
  49. /* Initialize some global variables */
  50.     x_fact = 1.0;
  51.     y_fact = 1.0;
  52.     d_phi  = 0.0;
  53.     n_steps= 100;
  54.     r_phi  = 3.0;
  55.     bAutoRotate = FALSE;
  56.     r_speed = 500;
  57.     iDirection = 1;
  58.  
  59. /*  we need a Menu Handle cause we want to manipulate the
  60.     pulldown entries (checkmarks) */
  61.     hMenu = LoadMenu(hInst,"LissajousMenu");
  62.  
  63.     hWnd= CreateWindow("LissajousWClass","Karsten's Lissajou 1.0"
  64.                        ,WS_OVERLAPPEDWINDOW
  65.                        ,CW_USEDEFAULT,CW_USEDEFAULT,220,229
  66.                        ,(HWND) NULL
  67.                        ,hMenu
  68.                        ,hInstance
  69.                        , NULL);
  70.  
  71.     if (!hWnd)
  72.         return(FALSE); /* window could not be created */
  73.  
  74.     ShowWindow(hWnd, nCmdShow);
  75.     UpdateWindow(hWnd);
  76.  
  77. /*  dispatch the messages
  78.     somewhat extended cause we use an AcceleratorTable */
  79.  
  80.     while (GetMessage(&msg,NULL,NULL,NULL))
  81.     {
  82.         if (!TranslateAccelerator(hWnd, hAccTable, &msg))
  83.         {
  84.             TranslateMessage(&msg);
  85.             DispatchMessage(&msg);
  86.         }
  87.     }
  88.     return (msg.wParam);
  89. }
  90.  
  91. BOOL InitApplication(hInstance)
  92. HANDLE hInstance;
  93. {
  94.     WNDCLASS wc;
  95.  
  96. /*  the windowclass.style should be defined such that Windows automatically
  97.     sends a WM_PAINT on resizing the window */
  98.  
  99.     wc.style = CS_HREDRAW | CS_VREDRAW;
  100.     wc.lpfnWndProc = MainWndProc;
  101.     wc.cbClsExtra = 0;
  102.     wc.cbWndExtra = 0;
  103.     wc.hInstance = hInstance;
  104.     wc.hIcon = LoadIcon(hInstance, "LissajousIcon");
  105.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  106.     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  107.     wc.lpszMenuName = "LissajousMenu";
  108.     wc.lpszClassName= "LissajousWClass";
  109.  
  110.     return (RegisterClass(&wc));
  111. }
  112.  
  113. long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
  114. HWND hWnd;
  115. unsigned message;
  116. WORD wParam;
  117. LONG lParam;
  118. {
  119.     FARPROC      lpProcAbout
  120.                 ,lpProcSetParams
  121.                 ,lpProcStatusBox;
  122.     PAINTSTRUCT  ps;
  123.     HDC          hDC;
  124.  
  125.     switch (message)
  126.     {
  127.         case WM_CREATE:
  128.             hAccTable = LoadAccelerators(hInst,"LissajousMenu");
  129.             break;
  130.  
  131.         case WM_INITDIALOG:
  132.             return (TRUE);
  133.             break;
  134.  
  135. /*  if we select the Autorotate feature then every timer click the
  136.     Lissajou-Application sends a message containing the order to
  137.     turn left or right: this is similar to a computer hitting its own
  138.     keys... */
  139.  
  140.         case WM_TIMER:
  141.             if (iDirection==1)
  142.                 SendMessage(hWnd, (WORD) WM_COMMAND, (WORD) IDM_RIGHTTURN, (LONG) NULL);
  143.             else
  144.                 SendMessage(hWnd, (WORD) WM_COMMAND, (WORD) IDM_LEFTTURN, (LONG) NULL);
  145.             break;
  146.  
  147.         case WM_COMMAND:
  148.             switch (wParam)
  149.             {
  150.                 case IDM_ABOUT:
  151.                     lpProcAbout = MakeProcInstance(About,hInst);
  152.                     DialogBox(hInst,"AboutBox",hWnd,lpProcAbout);
  153.                     FreeProcInstance(lpProcAbout);
  154.                     break;
  155.  
  156.                 case IDM_SETPAR:
  157.                     lpProcSetParams = MakeProcInstance(SetParams,hInst);
  158.                     DialogBox(hInst,"SetParams",hWnd,lpProcSetParams);
  159.                     FreeProcInstance(lpProcSetParams);
  160.                     InvalidateRect(hWnd, NULL,TRUE);
  161.                     if (bStatusBox) InvalidateRect(hStatusBox,NULL,FALSE);
  162.                     break;
  163.  
  164.                 case IDM_LEFTTURN:
  165.                     d_phi -= r_phi;
  166.                     if (d_phi<0.0) d_phi += 360.0;
  167.                     iDirection = -1;
  168.                     InvalidateRect(hWnd, NULL, TRUE);
  169.                     if (bStatusBox) InvalidateRect(hStatusBox,NULL,FALSE);
  170.                     break;
  171.  
  172.                 case IDM_RIGHTTURN:
  173.                     d_phi += r_phi;
  174.                     if (d_phi>360.0) d_phi -= 360.0;
  175.                     iDirection = 1;
  176.                     InvalidateRect(hWnd, NULL, TRUE);
  177.                     if (bStatusBox) InvalidateRect(hStatusBox,NULL,FALSE);
  178.                     break;
  179.  
  180. /*  autorotate feature keeps track of its status in bAutoRotate. If it is
  181.     switched on it starts a timer, when it is switched off, it kills that
  182.     timer */
  183.                 case IDM_AUTOROTATE:
  184.                     if (bAutoRotate)
  185.                     {
  186.                         bAutoRotate = FALSE;
  187.                         CheckMenuItem(hMenu, IDM_AUTOROTATE, MF_UNCHECKED);
  188.                         KillTimer(hWnd, 1);
  189.                     }
  190.                     else
  191.                     {
  192.                         bAutoRotate = TRUE;
  193.                         CheckMenuItem(hMenu, IDM_AUTOROTATE, MF_CHECKED);
  194.                         idTimer = SetTimer(hWnd, 1, r_speed, (FARPROC) NULL);
  195.                     }
  196.                     break;
  197.  
  198. /*  here we make use of a modeless dialog box: this is because we want to
  199.     have the status box displayed and want to continue work somewhere else */
  200.                 case IDM_STATUSBOX:
  201.                     if (bStatusBox)
  202.                     {
  203.                         bStatusBox = FALSE;
  204.                         CheckMenuItem(hMenu, IDM_STATUSBOX, MF_UNCHECKED);
  205.                         ShowWindow(hStatusBox,SW_HIDE);
  206.                         DestroyWindow(hStatusBox);
  207.                         FreeProcInstance(lpProcStatusBox);
  208.                     }
  209.                     else
  210.                     {
  211.                         bStatusBox = TRUE;
  212.                         CheckMenuItem(hMenu, IDM_STATUSBOX, MF_CHECKED);
  213.  
  214.                         lpProcStatusBox = MakeProcInstance(StatusBox,hInst);
  215.                         hStatusBox=CreateDialog(hInst,"StatusBox",hWnd,lpProcStatusBox);
  216.                     }
  217.                     break;
  218.  
  219.                 default:
  220.                     return (DefWindowProc(hWnd,message,wParam,lParam));
  221.             }
  222.             break;
  223.  
  224.         case WM_PAINT:
  225.             {
  226.                 WORD wViewX, wViewY;
  227.                 RECT rcClient;
  228.  
  229.                 hDC = BeginPaint (hWnd,&ps);
  230.  
  231.                 GetClientRect(hWnd,&rcClient);
  232.                 wViewX = rcClient.right - rcClient.left - 1;
  233.                 wViewY = rcClient.bottom - rcClient.top - 1;
  234.                 SetViewportExt(hDC,wViewX,wViewY);
  235.  
  236.                 LissajousPlot(hDC, wViewX, wViewY);
  237.  
  238.                 EndPaint (hWnd,&ps);
  239.             }
  240.             break;
  241.  
  242.         case WM_DESTROY:
  243.             PostQuitMessage(0);
  244.             break;
  245.  
  246.         default:
  247.             return (DefWindowProc(hWnd,message,wParam,lParam));
  248.     }
  249.     return(NULL);
  250. }
  251.  
  252. BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
  253. HWND hDlg;
  254. unsigned message;
  255. WORD wParam;
  256. LONG lParam;
  257. {
  258.     switch (message)
  259.     {
  260.         case WM_INITDIALOG:
  261.             return(TRUE);
  262.  
  263.         case WM_COMMAND:
  264.             if (wParam == IDOK || wParam == IDCANCEL)
  265.             {
  266.                 EndDialog(hDlg,TRUE);
  267.                 return(TRUE);
  268.             }
  269.             break;
  270.     }
  271.     return(FALSE);
  272. }
  273.  
  274. BOOL FAR PASCAL SetParams(hDlg, message, wParam, lParam)
  275. HWND hDlg;
  276. unsigned message;
  277. WORD wParam;
  278. LONG lParam;
  279. {
  280.     char szTmp[127];
  281.  
  282.     switch (message)
  283.     {
  284.         case WM_INITDIALOG:
  285.             sprintf(szTmp,"%9.1f",x_fact);
  286.             SetDlgItemText(hDlg,IDM_XFACTOR,szTmp);
  287.             sprintf(szTmp,"%9.1f",y_fact);
  288.             SetDlgItemText(hDlg,IDM_YFACTOR,szTmp);
  289.             sprintf(szTmp,"%9.1f",d_phi);
  290.             SetDlgItemText(hDlg,IDM_PHISHIFT,szTmp);
  291.             SetDlgItemInt(hDlg,IDM_NSTEPS,n_steps,TRUE);
  292.             sprintf(szTmp,"%9.1f",r_phi);
  293.             SetDlgItemText(hDlg,IDM_PHIROTATE,szTmp);
  294.             SetDlgItemInt(hDlg,IDM_ROTATESPEED,r_speed,TRUE);
  295.             return(TRUE);
  296.  
  297.         case WM_COMMAND:
  298.             switch (wParam)
  299.             {
  300.                 case IDOK:
  301.                     GetDlgItemText(hDlg,IDM_XFACTOR,szTmp,127);
  302.                     sscanf(szTmp,"%f",&x_fact);
  303.                     if (x_fact<0.0) x_fact = 1.0;
  304.                     GetDlgItemText(hDlg,IDM_YFACTOR,szTmp,127);
  305.                     sscanf(szTmp,"%f",&y_fact);
  306.                     if (y_fact<0.0) y_fact = 1.0;
  307.                     GetDlgItemText(hDlg,IDM_PHISHIFT,szTmp,127);
  308.                     sscanf(szTmp,"%f",&d_phi);
  309.                     if (d_phi<0.0) d_phi = 0.0;
  310.                     while (d_phi>360.0) d_phi -= 360.0;
  311.                     GetDlgItemText(hDlg,IDM_NSTEPS,szTmp,127);
  312.                     sscanf(szTmp,"%d",&n_steps);
  313.                     if (n_steps<3) n_steps = 3;
  314.                     GetDlgItemText(hDlg,IDM_PHIROTATE,szTmp,127);
  315.                     sscanf(szTmp,"%f",&r_phi);
  316.                     GetDlgItemText(hDlg,IDM_ROTATESPEED,szTmp,127);
  317.                     sscanf(szTmp,"%d",&r_speed);
  318.                     if (r_speed < 100) r_speed = 100;
  319.  
  320.                     EndDialog(hDlg,TRUE);
  321.                     return(TRUE);
  322.                     break;
  323.  
  324.                 case IDCANCEL:
  325.                     EndDialog(hDlg,TRUE);
  326.                     return(TRUE);
  327.                     break;
  328.             }
  329.             break;
  330.     }
  331.     return(FALSE);
  332. }
  333.  
  334.  
  335. void LissajousPlot(hDC, x_win, y_win)
  336. HDC hDC;
  337. WORD x_win,y_win;
  338. {
  339.     float phi,phi_step,radians;
  340.     int ijk, x, y;
  341.  
  342.     phi_step = 360.0 / (float) n_steps;
  343.     radians = 3.1415926 / 180.0;
  344.  
  345.     x= x_win/2;
  346.     y= y_win/2 + (int) ((y_win/2.2) * cos(y_fact*d_phi*radians));
  347.     MoveTo(hDC,x,y);
  348.  
  349.     for (ijk=0;ijk<=n_steps;ijk++)
  350.     {
  351.         phi = ijk*phi_step * radians;
  352.         x = x_win/2 + (int)((x_win/2.2) * sin(x_fact*phi));
  353.         y = y_win/2 + (int)((y_win/2.2) * cos(y_fact*(phi+d_phi*radians)));
  354.         LineTo(hDC,x,y);
  355.     }
  356. }
  357.  
  358. BOOL FAR PASCAL StatusBox(hDlg, message, wParam, lParam)
  359. HWND hDlg;
  360. unsigned message;
  361. WORD wParam;
  362. LONG lParam;
  363. {
  364.     char szTmp[127];
  365.     PAINTSTRUCT ps;
  366.     HDC hDC;
  367.  
  368.     switch (message)
  369.     {
  370.         case WM_PAINT:
  371.             hDC = BeginPaint (hDlg,&ps);
  372.             sprintf(szTmp,"%9.1f",x_fact);
  373.             SetDlgItemText(hDlg,IDM_STATX,szTmp);
  374.             sprintf(szTmp,"%9.1f",y_fact);
  375.             SetDlgItemText(hDlg,IDM_STATY,szTmp);
  376.             sprintf(szTmp,"%9.1f",d_phi);
  377.             SetDlgItemText(hDlg,IDM_STATP,szTmp);
  378.             sprintf(szTmp,"%d",n_steps);
  379.             SetDlgItemText(hDlg,IDM_STATNS,szTmp);
  380.             sprintf(szTmp,"%9.1f",r_phi);
  381.             SetDlgItemText(hDlg,IDM_STATR,szTmp);
  382.             sprintf(szTmp,"%d",r_speed);
  383.             SetDlgItemText(hDlg,IDM_STATRS,szTmp);
  384.             EndPaint (hDlg,&ps);
  385.             break;
  386.  
  387.         case WM_INITDIALOG:
  388.             sprintf(szTmp,"%9.1f",x_fact);
  389.             SetDlgItemText(hDlg,IDM_STATX,szTmp);
  390.             sprintf(szTmp,"%9.1f",y_fact);
  391.             SetDlgItemText(hDlg,IDM_STATY,szTmp);
  392.             sprintf(szTmp,"%9.1f",d_phi);
  393.             SetDlgItemText(hDlg,IDM_STATP,szTmp);
  394.             sprintf(szTmp,"%d",n_steps);
  395.             SetDlgItemText(hDlg,IDM_STATNS,szTmp);
  396.             sprintf(szTmp,"%9.1f",r_phi);
  397.             SetDlgItemText(hDlg,IDM_STATR,szTmp);
  398.             sprintf(szTmp,"%d",r_speed);
  399.             SetDlgItemText(hDlg,IDM_STATRS,szTmp);
  400.             ShowWindow(hDlg,SW_SHOW);
  401.             return(TRUE);
  402.             break;
  403.     }
  404.     return(FALSE);
  405. }
  406.  
  407.